/*********************************** (C) COPYRIGHT ******************************
 * address: https://gitee.com/liuniansihuo/multitasks-os
 *
 * Change Logs:
 * Date			Author      	Notes
 * 2019-06-26	LiuHuo			first version
 *
*******************************************************************************/

#include "bitmap.h"


/* Count Leading Zeros (clz)
   counts the number of zero bits preceding the most significant one bit. */

unsigned char clz8(unsigned char x)
{
    unsigned char n = 0;

    if (x == 0) {
        return 8;
    }

    if ((x & 0XF0u) == 0) {
        x <<= 4;
        n += 4;
    }
    if ((x & 0XC0u) == 0) {
        x <<= 2;
        n += 2;
    }
    if ((x & 0X80u) == 0) {
        n += 1;
    }

    return n;
}

unsigned char clz16(unsigned short x)
{
    unsigned char n = 0;

    if (x == 0) {
        return 16;
    }

    if ((x & 0XFF00u) == 0) {
        x <<= 8;
        n += 8;
    }
    if ((x & 0XF000u) == 0) {
        x <<= 4;
        n += 4;
    }
    if ((x & 0XC000u) == 0) {
        x <<= 2;
        n += 2;
    }
    if ((x & 0X8000u) == 0) {
        n += 1;
    }

    return n;
}

unsigned char clz32(unsigned int x)
{
    unsigned char n = 0;

    if (x == 0) {
        return 32;
    }

    if ((x & 0XFFFF0000u) == 0) {
        x <<= 16;
        n += 16;
    }
    if ((x & 0XFF000000u) == 0) {
        x <<= 8;
        n += 8;
    }
    if ((x & 0XF0000000u) == 0) {
        x <<= 4;
        n += 4;
    }
    if ((x & 0XC0000000u) == 0) {
        x <<= 2;
        n += 2;
    }
    if ((x & 0X80000000u) == 0) {
        n += 1;
    }

    return n;
}

 unsigned char clz64(unsigned long long x)
{
    unsigned char n = 0;

    if (x == 0) {
        return 64;
    }

    if ((x & 0XFFFFFFFF00000000u) == 0) {
        x <<= 32;
        n += 32;
    }
    if ((x & 0XFFFF000000000000u) == 0) {
        x <<= 16;
        n += 16;
    }
    if ((x & 0XFF00000000000000u) == 0) {
        x <<= 8;
        n += 8;
    }
    if ((x & 0XF000000000000000u) == 0) {
        x <<= 4;
        n += 4;
    }
    if ((x & 0XC000000000000000u) == 0) {
        x <<= 2;
        n += 2;
    }
    if ((x & 0X8000000000000000u) == 0) {
        n += 1;
    }

    return n;
}


/* Count Trailing Zeros (ctz)
   counts the number of zero bits succeeding the least significant one bit. */

unsigned char ctz8(unsigned char x)
{
    unsigned char n = 0;

    if (x == 0) {
        return 8;
    }

    if ((x & 0X0000000F) == 0) {
        x >>= 4;
        n += 4;
    }
    if ((x & 0X00000003) == 0) {
        x >>= 2;
        n += 2;
    }
    if ((x & 0X00000001) == 0) {
        n += 1;
    }

    return n;
}
unsigned char ctz16(unsigned short x)
{
    unsigned char n = 0;

    if (x == 0) {
        return 16;
    }

    if ((x & 0X00FF) == 0) {
        x >>= 8;
        n += 8;
    }
    if ((x & 0X000F) == 0) {
        x >>= 4;
        n += 4;
    }
    if ((x & 0X0003) == 0) {
        x >>= 2;
        n += 2;
    }
    if ((x & 0X0001) == 0) {
        n += 1;
    }

    return n;
}
unsigned char ctz32(unsigned int x)
{
    unsigned char n = 0;

    if (x == 0) {
        return 32;
    }

    if ((x & 0X0000FFFF) == 0) {
        x >>= 16;
        n += 16;
    }
    if ((x & 0X000000FF) == 0) {
        x >>= 8;
        n += 8;
    }
    if ((x & 0X0000000F) == 0) {
        x >>= 4;
        n += 4;
    }
    if ((x & 0X00000003) == 0) {
        x >>= 2;
        n += 2;
    }
    if ((x & 0X00000001) == 0) {
        n += 1;
    }

    return n;
}

unsigned char ctz64(unsigned long long x)
{
    unsigned char n = 0;

     if (x == 0) {
        return 64;
    }

    if ((x & 0XFFFFFFFF00000000u) == 0) {
        x >>= 32;
        n += 32;
    }
    if ((x & 0XFFFF000000000000u) == 0) {
        x >>= 16;
        n += 16;
    }
    if ((x & 0XFF00000000000000u) == 0) {
        x >>= 8;
        n += 8;
    }
    if ((x & 0XF000000000000000u) == 0) {
        x >>= 4;
        n += 4;
    }
    if ((x & 0XC000000000000000u) == 0) {
        x >>= 2;
        n += 2;
    }
    if ((x & 0X8000000000000000u) == 0) {
        n += 1;
    }
    return n;
}



